<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        // 立即执行函数: 此类函数没有声明,在一次执行过后立即释放.适合做初始化工作
        // 最外层的小括号是数学符号-->（优先级高），最后一个小括号是执行符号
        // 只有表达式才能被执行符号执行
        // 被执行符号执行的表达式会自动放弃函数名称
        // (function() {
        //     console.log('a');
        // }())



        // function test() {
        //     var arr = [];
        //     for (var i = 0; i < 10; i++) {
        //         //立即执行函数
        //         (function(j) {
        //             arr[j] = function() {
        //                 console.log(j);
        //             }
        //         }(i))
        //     }
        //     return arr;
        // }
        // var myArr = test();
        // for (var j = 0; j < 10; j++) {
        //     myArr[j]();
        // }








        // var i = (function(x) {
        //     delete x; //形参x相当于var一个x,所以删除不掉
        //     return x;
        // }(2))
        // console.log(i);




        // var h = function a() {
        //     return 23;
        // }
        // typeof a(); //声明函数后加函数名会报错



        //闭包
        // 当内部函数被保存到外部时，将会生成闭包。
        // 闭包会导致原有作用域链不释放，造成内存泄露(占用)。
        // function a() {
        //     function b() {
        //         var bbb = 234;
        //         console.log(aaa);
        //     }
        //     var aaa = 123;
        //     return b;
        // }
        // var glob = 100;
        // var demo = a();
        // demo();



        // 闭包的作用
        //     实现共有变量
        //     可以做缓存（存储结构）
        //     可以实现封装，属性私有化
        //     模块化开发，防止污染全局变量

        // 函数累加器
        // function add() {
        //     var num = 0;

        //     function a() {
        //         console.log(++num);
        //     }
        //     return a;
        // }
        // var myAdd = add();
        // for (var i = 0; i < 10; i++) {
        //     myAdd();
        // }



        // 同时保存两个函数
        // function test() {
        //     var num = 100;

        //     function a() {
        //         num++;
        //         console.log(num);
        //     }

        //     function b() {
        //         num--;
        //         console.log(num);
        //     }
        //     return [a, b];
        // }
        // var myArr = test();
        // myArr[0]();
        // myArr[1]();



        // 缓存（eater）
        // function test() {
        //     var food = "apple";
        //     var obj = {
        //         eatFood: function() {
        //             if (food != "") {
        //                 console.log("I am eating " + food);
        //                 food = "";
        //             } else {
        //                 console.log("There id nothing! empty");
        //             }
        //         },
        //         pushFood: function(myFood) {
        //             food = myFood;
        //         }
        //     }
        //     return obj;
        // }
        // var person = test();
        // person.eatFood();
        // person.eatFood();
        // person.pushFood("banana");
        // person.eatFood();


        //小陷阱
        // var x = 1;
        // if (function() {}) {
        //     x += typeof f;
        // }
        // console.log(x);


        //实现封装，属性私有化,不污染全局变量
        // function Huang(name, wife) {
        //     var prepareWife = 'little dog';

        //     this.name = name;
        //     this.wife = wife;
        //     this.divoce = function() {
        //         this.wife = prepareWife;
        //     }
        //     this.changePrepareWife = function(target) {
        //         prepareWife = target;
        //     }
        //     this.sayPrapreWife = function() {
        //         console.log(prepareWife);
        //     }
        // }

        // var huang = new Huang('huang', 'little cat');
        // console.log(huang);




        // 闭包的防范
        // 闭包会导致多个执行函数共用一个共有变量，如果不是特殊需要
        // 应尽量防止这种情况发生

        // function test() {
        //     var arr = [];
        //     for (var i = 0; i < 10; i++) {
        //         arr[i] = function() {
        //             console.log(i);
        //         }
        //     }
        //     return arr;
        // }
        // var myArr = test();
        // for (var j = 0; j < 10; j++) {
        //     myArr[j]();
        // } //保存了十个函数，结果是10个10

        // 解决方法
        // function test() {
        //     var arr = [];
        //     for (var i = 0; i < 10; i++) {
        //         (function(j) {
        //             // j=1
        //             arr[j] = function() {
        //                 console.log(j);
        //             }
        //         }(i)) //这个时候找的就是立即执行函数中的j
        //     }
        //     return arr;
        // }
        // var myArr = test();
        // for (var j = 0; j < 10; j++) {
        //     myArr[j]();
        // }







        // 不依赖于外部变量，能反复执行的函数累加器
        // function add() {
        //     var num = 0;

        //     function a() {
        //         console.log(++num);
        //     }
        //     return a;
        // }
        // var myAdd = add();
        // for (var i = 0; i < 20; i++) {
        //     myAdd();
        // }





        //简化下列代码，使其看起来更优雅
        // function getDay() {
        //     switch (day) {
        //         case 1:
        //             console.log('一');
        //             break;
        //         case 2:
        //             console.log('二');
        //             break;
        //         case 3:
        //             console.log('三');
        //             break;
        //         case 4:
        //             console.log('四');
        //             break;
        //         case 5:
        //             console.log('五');
        //             break;
        //         case 6:
        //             console.log('六');
        //             break;
        //         case 7:
        //             console.log('七');
        //             break;
        //             default:
        //                 console.log('Error');
        //     }
        // }

        // function retDate(date) {
        //     var arr = ['一', '二', '三', '四', '五', '六', '七'];
        //     var ret = arr[date - 1];
        //     if (ret === undefined) {
        //         return 'Error';
        //     } else {
        //         return ret;
        //     }
        // }
        // console.log(retDate(1));





        // var a = (2, 3); //逗号操作符，返回逗号后面的结果
        // var f = (
        //     function f() {
        //         return '1';
        //     },
        //     function g() {
        //         return 2;
        //     }
        // )();
        // console.log(typeof(f));
    </script>
</head>

<body>
</body>

</html>